package com.euq.log;

import com.euq.dto.OperationLogDto;
import com.euq.mq.OperationLogProducer;
import com.euq.utils.SecurityUtils;
import com.euq.dto.LoginUser;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class OperationLogAspect {

    @Autowired
    private OperationLogProducer operationLogProducer;

    @Around("@annotation(businessLog)")
    public Object logOperation(ProceedingJoinPoint joinPoint, BusinessLog businessLog) throws Throwable {
        Object result;
        Exception exception = null;
        try {
            result = joinPoint.proceed();
            return result;
        } catch (Exception e) {
            exception = e;
            throw e;
        } finally {
            sendLog(joinPoint, businessLog, exception == null);
        }
    }


    private void sendLog(ProceedingJoinPoint joinPoint, BusinessLog annotation, boolean success) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Class<?> clazz = method.getDeclaringClass();

        LoginUser loginUser = SecurityUtils.getCurrentUser();

        OperationLogDto logDTO = new OperationLogDto();
        logDTO.setClassName(clazz.getSimpleName());
        logDTO.setMethod(method.getName());
        logDTO.setLogName(annotation.logName());
        logDTO.setLogType(annotation.logType());
        logDTO.setMessage(annotation.logName() + (success ? "成功" : "失败"));
        logDTO.setSucceed(String.valueOf(success));
        logDTO.setUserId(loginUser != null ? loginUser.getUser().getId() : null);

        operationLogProducer.sendOperationLog("operation-topic", logDTO);
    }
}
